package com.example.frenchconjugationquiz;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.res.AssetManager;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import au.com.bytecode.opencsv.CSVReader;

import com.example.frenchconjugationquiz.data.CSVDataAdapter;
import com.example.frenchconjugationquiz.data.ConjugationDataSource;
import com.example.frenchconjugationquiz.data.ConjugationModel;
import com.example.frenchconjugationquiz.gui.CustomTextView;
import common.Utility;

public class SinglePlayerActivity extends FragmentActivity
{

	FillDataTask task;
	ProgressDialog progressDialog;
	ConjugationDataSource dataSource;
	static Typeface tf;

	private String CSV_PATH = "french-verb-conjugation-simplified.csv";
	
	// When requested, this adapter returns a DemoObjectFragment, representing
	// an object in the collection.
	QuestionPagerAdapter mQuestionPagerAdapter;
	ViewPager mViewPager;

	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_single_player);
		tf = Typeface.createFromAsset(getAssets(), "SFArchRival.ttf");

		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

		Utility.Log("SinglePlayerQuizActivity created, opening DB");
		dataSource = new ConjugationDataSource(this);
		dataSource.open();
		if (dataSource.getCount() == 0)
		{
			clearData();
			fillData();
		}
		else
		{
			// add first question
			initUI();
		}
	}

	private void clearData()
	{
		Utility.Log("Clearing DB");
		dataSource.clearData();
	}

	private void fillData()
	{
		Utility.Log("fillData trying to parse csv");
		AssetManager assetManager = this.getAssets();

		InputStream csvStream;
		try
		{
			csvStream = assetManager.open(CSV_PATH);
			task = new FillDataTask(this);
			task.execute(csvStream);
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	protected void onPause()
	{
		if (progressDialog != null)
			progressDialog.dismiss();
		super.onPause();
	}

	@Override
	protected void onDestroy()
	{
		Utility.Log("SinglePlayerQuizActivity destroyed, closing DB");
		dataSource.close();
		super.onDestroy();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_single_player_quiz, menu);
		return true;
	}

	private void initUI()
	{
		// ViewPager and its adapters use support library fragments, so use
		// getSupportFragmentManager.
		mQuestionPagerAdapter = new QuestionPagerAdapter(getSupportFragmentManager());
		mViewPager = (ViewPager) findViewById(R.id.pager);
		mViewPager.setAdapter(mQuestionPagerAdapter);
	}

	private class FillDataTask extends AsyncTask<InputStream, Integer, Long>
	{
		private Context context;
		private String message = "Please wait while the conjugation table is downloaded ";

		public FillDataTask(Context context)
		{
			this.context = context;
		}

		@Override
		protected void onPreExecute()
		{
			super.onPreExecute();
			if (isCancelled())
				return;

			progressDialog = new ProgressDialog(context);
			progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener()
			{
				public void onCancel(DialogInterface dialog)
				{
					task.cancel(true);
					Utility.Log("Task cancelled.");
				}
			});
			progressDialog.setMessage(message);
			progressDialog.setCancelable(true);
			progressDialog.setIndeterminate(false);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			progressDialog.setMax(100);
			progressDialog.setProgress(0);
			progressDialog.show();
		}

		protected Long doInBackground(InputStream... csvStream)
		{
			Utility.Log("Task started.");
			progressDialog.setProgress(0);
			try
			{

				Utility.Log("fillData from CSV");

				InputStreamReader csvStreamReader = new InputStreamReader(csvStream[0]);
				CSVReader csvReader = new CSVReader(csvStreamReader);

				String[] line;
				// throw away the header
				csvReader.readNext();
				while ((line = csvReader.readNext()) != null)
				{
					if (isCancelled())
						break;
					int total = CSVDataAdapter.addToDataSource(line, dataSource);
					Utility.Log(String.valueOf(total));
					publishProgress(total);
				}
				csvReader.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}

			Utility.Log("Task finished.");
			return Long.MIN_VALUE;
		}

		protected void onProgressUpdate(Integer... progress)
		{
			int percentage = progress[0] * 100 / CSVDataAdapter.TOTAL_ENTRIES;
			Utility.Log("setting progress to " + progress[0]);
			progressDialog.setMessage(message + " : " + progress[0] + " of " + CSVDataAdapter.TOTAL_ENTRIES);
			progressDialog.setProgress(percentage);
		}

		protected void onPostExecute(Long result)
		{
			progressDialog.dismiss();
			// add first question
			initUI();
		}
	}
}

// Since this is an object collection, use a FragmentStatePagerAdapter and NOT a
// FragmentPagerAdapter.
class QuestionPagerAdapter extends FragmentStatePagerAdapter
{
	public QuestionPagerAdapter(FragmentManager fragmentManager)
	{
		super(fragmentManager);
	}

	@Override
	public Fragment getItem(int i)
	{
		Fragment fragment = new QuestionFragment();
		Bundle args = new Bundle();

		args.putInt(QuestionFragment.ARG_OBJECT, i + 1);
		fragment.setArguments(args);
		return fragment;
	}

	@Override
	public int getCount()
	{
		return 100;
	}

	@Override
	public CharSequence getPageTitle(int position)
	{
		return "OBJECT " + (position + 1);
	}
}

// Instances of this class are fragments representing a single object in our
// collection.
class QuestionFragment extends Fragment
{
	public static final String ARG_OBJECT = "object";
	CustomTextView tvSubject, tvVerb, tvTense, tvAnswer;
	TextView tvPageid;
	LinearLayout llAnswer;
	ImageButton btAnswer;
	static ConjugationDataSource dataSource;
	ConjugationModel questionModel;
	int pageId = 0;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
	{
		View rootView = initUI(inflater, container);

		// TODO: Make sure datasource is not null before we even get here.
		// init datasource once.
		if (dataSource == null)
			dataSource = ((SinglePlayerActivity) getActivity()).dataSource;
		dataSource.open();

		questionModel = dataSource.getRandomModel();
		fillData(questionModel);

		return rootView;
	}

	private View initUI(LayoutInflater inflater, ViewGroup container)
	{
		// The last two arguments ensure LayoutParams are inflated properly.
		View rootView = inflater.inflate(R.layout.question, container, false);
		tvSubject = (CustomTextView) rootView.findViewById(R.id.cctext_subject);
		tvVerb = (CustomTextView) rootView.findViewById(R.id.cctext_verb);
		tvTense = (CustomTextView) rootView.findViewById(R.id.cctext_tense);
		tvPageid = (TextView) rootView.findViewById(R.id.cctext_page_id);
		tvAnswer = (CustomTextView) rootView.findViewById(R.id.cctext_answer);
		llAnswer = (LinearLayout) rootView.findViewById(R.id.ll_answer);
		btAnswer = (ImageButton) rootView.findViewById(R.id.btn_answer);

		// on click, show the conjugation
		btAnswer.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				tvAnswer.setVisibility(View.VISIBLE);
				llAnswer.setVisibility(View.GONE);
			}
		});

		// Set font
		tvSubject.setTypeface(SinglePlayerActivity.tf);
		tvVerb.setTypeface(SinglePlayerActivity.tf);
		tvTense.setTypeface(SinglePlayerActivity.tf);
		tvAnswer.setTypeface(SinglePlayerActivity.tf);
		tvPageid.setTypeface(SinglePlayerActivity.tf);

		return rootView;
	}

	private void fillData(ConjugationModel model)
	{
		tvSubject.setText(model.getSubject());
		tvVerb.setText(model.getVerb());
		tvTense.setText(model.getTense());
		tvAnswer.setText(model.getConjugation());

		pageId = getArguments().getInt(ARG_OBJECT);
		tvPageid.setText(String.valueOf(pageId));
	}
}
